<html>
  <head>
  <title></title>
  <style>
    
    @import url(vgrid.css);
    
    table { style-set: vgrid; // see vgrid.css
            width:*;
            height:*; } 

    table th:first-child { width:8em; }    
    table th:nth-child(2) { width:*; }
    table th:last-child { width:8em; }

    table th[order=ascend]  {
      foreground-image:url(stock:arrow-down);
      foreground-repeat:no-repeat;
      foreground-position:100% 50%;
    } 
    table th[order=descend]  {
      foreground-image:url(stock:arrow-up);
      foreground-repeat:no-repeat;
      foreground-position:100% 50%;
    } 
      
  </style>
  <script type="text/tiscript">
  
  function self.ready() {
  
    var records = new Array(500);
    
    for(var i = 0; i < records.length; ++i)
      records[i] = {index: i, caption:"Item" + rand(records.length), status:"" };

    var n = records.length;
    var p = 0;
       
    var vlist = $(table);
    
    // feed it by these records
    vlist.value = records;

    // setting first item as current:    
    vlist.tbody.currentIndex = 0;
    
    $(#mutate) << event click() {
    
      function add() { 
        var at = rand(records.length + 1);
        records.splice(at,0, {index: ++n, caption:"Item", status:"Added" });
      }
      
      function del() { 
        var at = rand(records.length);
        var r = records[at];
        records.splice(at,1);
      }
      
      function upd() { 
        var at = rand(records.length);
        var r = records[at];
        var times = r.nupdates || 0;
        ++times;
        r.nupdates = times;
        r.status = String.$(Updated {times});
      }
      
      function noop() {}
      
      var ops = [add,del,upd,noop];

      self.timer(60ms, function() {
        if(!vlist.animating) // prevent updates on animation
          ops[ rand(ops.length) ]();
        return true;
      });

    }
    
    $(#populate) << event click() {
    
      records.splice(0,records.length); // clear the list

      function addChunk() {
        var n = 1 + rand(5);    
        for(var i = 0; i < n; ++i)
          records.push {index: records.length, caption:"New item", status:"" };
      }
      
      this.timer(100ms, function() {
        if(records.length > 200)
          return false; // enough is enough
        if(!vlist.animating) // prevent updates on animation
          addChunk();
        return true;
      });
    
    }
    
    $(#addone) << event click()
    {
	    records.push {index: records.length, caption:"New item", status:"" };
	    vlist.tbody.scrollTo(0, 9999999, true, true);
    }
    $(#copy) << event click() 
    {
      view.clipboard(#put,records[vlist.tbody.currentIndex].data);
    }
    $(#deleteall) << event click() 
    {
      //records.length = 0;
      records.splice(0,records.length);
    }
    $(#delete) << event click() 
    {
      records.splice(vlist.tbody.currentIndex,1);
    }

    $(#toLast) << event click() 
    {
      vlist.tbody.currentIndex = records.length - 1; 
    }    
        
    vlist << event change {
      stdout.println("change", vlist.tbody.currentIndex)
    }

    vlist << event dblclick $(tr) {
      stdout.println("dblclick", vlist.tbody.currentIndex)
    }

    vlist << event click $(th.sortable) 
    {
      var name = this.attributes["name"];
      var order = this.attributes["order"];

      function cmpascend(a,b) {
        if( a[name] > b[name] ) return 1;
        else if (a[name] < b[name]) return -1;
        return 0;
      }
      function cmpdescend(a,b) {
        if( a[name] < b[name] ) return 1;
        else if (a[name] > b[name]) return -1;
        return 0;
      }
    
      if ( order == "ascend" ) {
         this.attributes["order"] = "descend" ;
         records.sort(cmpdescend);
      } else if ( order == "descend" ){
         this.attributes["order"] = "ascend" ;
         records.sort(cmpascend);
      } else {
        // the column was not ordered before, remove @order from other columns
        if(var psort = this.parent.$(th[order]) )
           psort.attributes["order"] = undefined; // remove the attribute from previously ordered sibling
        // set this column as ascend order:
        this.attributes["order"] = "ascend";
        records.sort(cmpascend);
      }
    }

    
  }
  
  </script>
  </head>
<body>

  <h2>Dynamic recordset mutation in virtual table list</h2>
  
  <p>Records array is created with 500 records initially and gets modified dynamically (added,removed,updated). Each 60ms</p> 

  <button #populate>Simulate gradual population</button>
  <button #mutate>Start random updates</button>
  
  <button #addone>add one</button>
  <button #toLast>go to last</button>
  <button #copy>copy</button>
  <button #deleteall>deleteall</button>
  <button #delete>delete</button>

  <table resizeable>
    <thead>
      <tr><th(index).sortable>index</th><th(caption).sortable>caption</th><th(status)>status</th></tr>
    </thead>
    <tbody>
      <tr><td(index)></td><td(caption)></td><td(status)></td></tr>
    </tbody>
  </table>
 
  
</body>
</html>
